package cz.muni.fi.pa165.travelagency.persistence;

import cz.muni.fi.pa165.travelagency.entities.PackageTour;
import java.util.List;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;

/**
 * @author Lukas Jungmann
 * @version 1.0
 */
@Repository
@Component
public class PackageTourDAO implements IPackageTourDAO {

    private static final Logger LOGGER = Logger.getLogger(PackageTourDAO.class.getName());

    @PersistenceContext
    private EntityManager em;

    public PackageTourDAO() {
    }

    /**
     * mainly for tests
     *
     * @param em
     */
    void setEntityManager(EntityManager em) {
        if (em == null) {
            throw new IllegalArgumentException("EntityManager is null.");
        }
        this.em = em;
    }

    @Override
    public void createPackageTour(PackageTour pt) {
        if (pt.getId() != null) {
            throw new IllegalStateException("unmanaged PackageTour");
        }
        if (pt.getCapacity() < 1) {
            throw new IllegalArgumentException("capacity must be greater then zero");
        }
        if (pt.getName() == null) {
            throw new IllegalArgumentException("name cannot be null");
        }
        if (pt.getDescription() == null) {
            throw new IllegalArgumentException("description cannot be null");
        }
        if (pt.getDestination() == null) {
            throw new IllegalArgumentException("destination cannot be null");
        }
        persist(pt);
    }

    @Override
    public void deletePackageTour(PackageTour pt) {
        if (pt == null) {
            throw new IllegalArgumentException("PackageTour (pt) cannot be null");
        }
        if (pt.getId() == null) {
            throw new IllegalStateException("ID cannot be null");
        }
        delete(pt.getId());
    }

    @Override
    public List<PackageTour> findAll() {
        try {
            return em.createNamedQuery("PackageTour.findAll").getResultList();
        } catch (Throwable t) {
            throw new DAOException(t.getMessage(), t);
        }
    }

    private PackageTour findByID(Long id) {
        return em.find(PackageTour.class, id);
    }


    @Override
    public PackageTour getPackageTour(Long id) {
        if (id == null) {
            throw new IllegalArgumentException("id cannot be null");
        }
        if (id < 1) {
            throw new IllegalArgumentException("id must be grater then zero");
        }
        return findByID(id);
    }

    @Override
    public void updatePackageTour(PackageTour pt) {
        if (pt == null) {
            throw new IllegalArgumentException("pt cannot be null");
        }
        if (pt.getId() == null) {
            throw new IllegalStateException("unmanaged PackageTour (pt.id is null)");
        }
        try {
            em.merge(pt);
        } catch (Throwable t) {
            throw new DAOException(t.getMessage(), t);
        }
    }

    private synchronized void persist(Object object) {
        try {
            em.persist(object);
        } catch (Throwable t) {
            throw new DAOException(t.getMessage(), t);
        }

    }

    private synchronized void delete(Long id) {
        try {
            PackageTour pt = em.find(PackageTour.class, id);
            if (pt != null) {
                em.remove(pt);
            }
        } catch (Throwable t) {
            throw new DAOException(t.getMessage(), t);
        }

    }

}
